﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    time = new QTimer(this);
    time->stop();
    time->setInterval(ui->timeSpinBox->value());

    connect(time,SIGNAL(timeout()),this,SLOT(on_sendButton_clicked()));
    initPort();
    showColon = true;

    timer0 = new QTimer;
    connect(timer0,&QTimer::timeout,this,&MainWindow::UpdatePort);//更新端口号
    timer0->start(1000);
    QStringList newPortStringList;
    const auto infos = QSerialPortInfo::availablePorts();
    for (const QSerialPortInfo &info : infos)
    {
        newPortStringList += info.portName();
    }
    //更新串口号
    if(newPortStringList.size() != oldPortStringList.size())
    {
        oldPortStringList = newPortStringList;
        ui->PortBox->clear();
        ui->PortBox->addItems(oldPortStringList);
    }

    txCount = 0;
    rxCount = 0;

    ui->timeSpinBox->setRange(1,100000);
    ui->timeSpinBox->setValue(1000);

    DisplayTimeStatus = false;
    DisplayFlag = true;

    ui->lcdNumber->setDigitCount(8);//设置能显示的位数
    ui->lcdNumber->setSegmentStyle(QLCDNumber::Flat);//设置显示外观
    ui->lcdNumber->setMode(QLCDNumber::Dec);//设置显示的模式为十进制
    ui->lcdNumber->setStyleSheet("border: 1px solid green; color: green; background: silver;");//设置样式

    timer = new QTimer(this);//新建一个定时器对象
    timer->setInterval(1000);//设置定时器每过多少毫秒发送一个信号
    timer->start();//启动定时器
    connect(timer, &QTimer::timeout, this, &MainWindow::showTime);

    ui->sendButton->setEnabled(false);
    ui->sHexRadio->setEnabled(false);
    ui->sTextRadio->setChecked(true);
    ui->sTextRadio->setEnabled(false);
    ui->rTextRadio->setChecked(true);

    //connect(time, &QTimer::timeout, this, &MainWindow::on_sendButton_clicked);
    connect(ui->rHexRadio, &QRadioButton::toggled, this, &MainWindow::Mdisplay);
}
//更新端口号
void MainWindow::UpdatePort()
{
    QStringList newPortStringList;
    const auto infos = QSerialPortInfo::availablePorts();
    for (const QSerialPortInfo &info : infos)
    {
        newPortStringList += info.portName();
    }
    //更新串口号
    if(newPortStringList.size() != oldPortStringList.size())
    {
        oldPortStringList = newPortStringList;
        ui->PortBox->clear();
        ui->PortBox->addItems(oldPortStringList);
    }

}
//初始化串口
void MainWindow::initPort()
{
    //获取可用串口
    const auto infos = QSerialPortInfo::availablePorts();
    for(const QSerialPortInfo &info : infos)
    {
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite))
        {
            ui->PortBox->addItem(info.portName());
            qDebug()<<info.portName();
            serial.close();
        }
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}
//读取数据
void MainWindow::ReadData()
{
    QByteArray buf;

    buf = serialPort->readAll();
    qDebug()<<buf;

    if (!buf.isEmpty())
    {
        if(ui->showNumCB->isChecked())
        {
            dateTime = QDateTime::currentDateTime();
            QString str_time = QString("[%1]").arg(dateTime.toString("yyyy:MM:dd hh:mm:ss"));
            ui->recvtextBrowser->insertPlainText(str_time);
        }
        rxCount += buf.size();
        QString myStrTemp = QString::fromLocal8Bit(buf); //支持中文显示
        QString str = ui->recvtextBrowser->toPlainText();
        str += myStrTemp;
        //是否显示数据
        ui->recvtextBrowser->clear();

        if(DisplayFlag == true)
        {
            ui->recvtextBrowser->insertPlainText(str);
            ui->recvtextBrowser->moveCursor(QTextCursor::End);//将接收文本框的滚动条滑到最下面
        }


        ui->recvCntLineEdit->setText(tr("%1").arg(rxCount));
        show_portStateLabel();

        //自动换行
        if(ui->autoLineCB->isChecked())
        {
            ui->recvtextBrowser->insertPlainText("\n");
        }

        //自动保存
        QStringList myStrlist = myStrTemp.split(',');
        QString savetime = myStrlist.at(2);
        qDebug()<<savetime;
        QString yeartime = savetime.mid(0,4);
        QString monthtime = savetime.mid(4,2);
        QString daytime = savetime.mid(6,2);
        QString hourtime = savetime.mid(8,2);
        QString minutetime = savetime.mid(10,2);
        if(myStrTemp.startsWith("SR")&&hourtime=="24"&&minutetime=="00")
        {
            QString filename = "D:/"+yeartime + monthtime + daytime+".txt";
            QFile file(filename);
            if(!file.open(QFile::WriteOnly|QFile::Text))
            {
                QMessageBox::critical(this,tr("critical"),tr("无法写入数据！"),QMessageBox::Yes);
            }
            else
            {
                QTextStream out(&file);
                out<<ui->recvtextBrowser->toPlainText();
            }
        }
    }

    buf.clear();
}
//状态栏显示
void MainWindow::show_portStateLabel()
{
    QString info=QString("RX: %0     TX: %1 Bytes").arg(rxCount).arg(txCount);
    ui->portStateLabel->setText(info);
}
//设置串口参数
void MainWindow::on_openButton_clicked()
{
    if (ui->openButton->text() == tr("打开串口"))
    {
        serialPort = new QSerialPort;
        serialPort->setPortName(ui->PortBox->currentText());
        if(serialPort->open(QIODevice::ReadWrite))
        {
            //设置波特率
            //qDebug()<<ui->BaudBox->currentIndex();
            QString str_baudrae =  ui->BaudBox->currentText();

            serialPort->setBaudRate(str_baudrae.toInt());

            //设置停止位

        qDebug()<<ui->StopBox->currentIndex();

        switch (ui->StopBox->currentIndex())
            {
            case 0:
                serialPort->setStopBits(QSerialPort::OneStop);
                //qDebug()<<"one stop";
                break;
            case 1:
                serialPort->setStopBits(QSerialPort::TwoStop);
                //qDebug()<<"two stop";
                break;
            default:
                break;
            }

        qDebug()<<ui->DataBox->currentIndex();
            //设置数据位
            switch (ui->DataBox->currentIndex())
            {
            case 0:
                serialPort->setDataBits(QSerialPort::Data8);
                //qDebug()<<"data wide 8";
                break;
            case 1:
                serialPort->setDataBits(QSerialPort::Data7);
                break;
            case 2:
                serialPort->setDataBits(QSerialPort::Data6);
                break;
            case 3:
                serialPort->setDataBits(QSerialPort::Data5);
                break;
            default:
                break;
            }
            //设置校验方式
            switch (ui->ParityBox->currentIndex())
            {
            case 0:
                serialPort->setParity(QSerialPort::NoParity);
                //qDebug()<<"no parity";
                break;
            default:
                break;
            }
            ui->openButton->setText(tr("关闭串口"));
            ui->PortBox->setEnabled(false);
            ui->BaudBox->setEnabled(false);
            ui->StopBox->setEnabled(false);
            ui->DataBox->setEnabled(false);
            ui->ParityBox->setEnabled(false);
            ui->sendButton->setEnabled(true);
            ui->sTextRadio->setEnabled(true);
            ui->sHexRadio->setEnabled(true);
            connect(serialPort, &QSerialPort::readyRead, this, &MainWindow::ReadData);
            ui->comLabel->setText(QString("串口号：%0   波特率：%1").arg(ui->PortBox->currentText()).arg(ui->BaudBox->currentText()));

        }
        else
        {
            QMessageBox::critical(this, tr("Error"), serialPort->errorString());
        }
    }
    else
    {
        serialPort->clear();
        serialPort->close();
        serialPort->deleteLater();
        ui->sendButton->setEnabled(false);
        ui->openButton->setText(tr("打开串口"));
        ui->PortBox->setEnabled(true);
        ui->BaudBox->setEnabled(true);
        ui->StopBox->setEnabled(true);
        ui->DataBox->setEnabled(true);
        ui->ParityBox->setEnabled(true);
        ui->sHexRadio->setEnabled(false);
        ui->sTextRadio->setEnabled(false);
        ui->comLabel->setText(tr("串口已关闭！"));
    }
}
//清除接收
void MainWindow::on_r_clearButton_clicked()
{
    ui->recvtextBrowser->clear();
}

void MainWindow::on_sendButton_clicked()
{
    QString str = ui->sendtextEdit->toPlainText();
    if(ui->newLineCB->isChecked())
    {
        if(!(str.endsWith("\r\n")))
        {
            str += "\r\n";
        }
    }
    if(!str.isEmpty())
    {
        auto isHexSend = ui->sHexRadio->isChecked();
        int len = str.length();
        txCount += len;
        show_portStateLabel();
        //qDebug()<<txCount;
        ui->sendCntLineEdit->setText(tr("%1").arg(txCount));
       int data;
       QByteArray send_data;

        if(isHexSend)
        {
            /*if(len%2 == 1)
            {
                str = str.insert(len-1,' ');
            }*/
            QStringList list = str.split(' ');
            QString data2;
            //data = str.toInt(nullptr,16);
            send_data.resize(list.size());
            for(int i=0;i<list.size();i++)
            {
                data2 = list.at(i);
                data = data2.toInt(nullptr,16);
                send_data[i] = data;
                qDebug()<<data;
            }
            if(serialPort->write(send_data)<0)
            {
                QMessageBox::critical(this, tr("Error"), serialPort->errorString());
            }

        }
        else
        {
            if(serialPort->write(str.toLocal8Bit())<0)
            {
                QMessageBox::critical(this, tr("Error"), serialPort->errorString());
            }
        }
        //接收区显示发送区的内容
        auto isredisplay = ui->reDisplay->isChecked();
        if(isredisplay)
        {
            ui->recvtextBrowser->append(str);
        }
        send_data.clear();
    }
    str.clear();
}

void MainWindow::readToHex()
{
    QByteArray temp = serialPort->readAll();
    QDataStream out(&temp,QIODevice::ReadWrite);
    //将字节数组读入
    while(!out.atEnd())
    {
        qint8 outChar = 0;
        out>>outChar; //每字节填充一次，直到结束
        //十六进制的转换
        QString str = QString("%1").arg(outChar&0xFF,2,16,QLatin1Char('0'));
        ui->recvtextBrowser->insertPlainText(str.toUpper());//大写
        ui->recvtextBrowser->insertPlainText(" ");//每发送两个字符后添加一个空格
        ui->recvtextBrowser->moveCursor(QTextCursor::End);
    }
}

void MainWindow::Mdisplay()
{
    if(ui->rHexRadio->isChecked())
    {
        disconnect(serialPort, &QSerialPort::readyRead, this, &MainWindow::ReadData);
        connect(serialPort, &QSerialPort::readyRead, this, &MainWindow::readToHex);
    }
    else
    {
        connect(serialPort, &QSerialPort::readyRead, this, &MainWindow::ReadData);
        disconnect(serialPort, &QSerialPort::readyRead, this, &MainWindow::readToHex);
    }
}
//清除发送
void MainWindow::on_s_clearButton_clicked()
{
    ui->sendtextEdit->clear();
}
//清空计数
void MainWindow::on_resetCntButton_clicked()
{
    //ui->sendCntLineEdit->clear();
    txCount = 0;
    ui->sendCntLineEdit->setText(tr("%1").arg(txCount));
    //ui->recvCntLineEdit->clear();
    rxCount = 0;
    ui->recvCntLineEdit->setText(tr("%1").arg(txCount));
    show_portStateLabel();
}
//自动发送
void MainWindow::on_autoSendCB_clicked(bool checked)
{
    if(checked)
    {
        time->setInterval(ui->timeSpinBox->value());
        time->start();
        ui->timeSpinBox->setReadOnly(true);
    }
    else {
        time->stop();
        ui->timeSpinBox->setReadOnly(false);
    }
}
//保存数据
void MainWindow::on_saveButton_clicked()
{
        SaveAs();
}
bool MainWindow::SaveAs()
{
    QString curFile;
    QString fileName = QFileDialog::getSaveFileName(this,tr("另存为"),curFile,tr("TXT文档(*.txt);;所有文件(*.*)"));
    if(fileName.isEmpty())
    {
        return false;
    }
    if(!(fileName.endsWith(".txt",Qt::CaseInsensitive)))
    {
        fileName += ".txt";
    }
    QFile file(fileName);
    if(!file.open(QFile::WriteOnly|QFile::Text))
    {
        QMessageBox::critical(this,tr("critical"),tr("无法写入数据！"),QMessageBox::Yes);
        return false;
    }
    else
    {
        QTextStream out(&file);
        out<<ui->recvtextBrowser->toPlainText();
        return true;
    }
}
//停止接收显示
void MainWindow::on_recvStopButton_clicked()
{
    if(ui->recvStopButton->text() == tr("停止"))
    {
        DisplayFlag = false;
        ui->recvStopButton->setText(tr("继续"));
    }
    else {
        DisplayFlag = true;
        ui->recvStopButton->setText(tr("停止"));
    }
}
//显示当前时间
void MainWindow::showTime()
{
    //获取系统当前时间
    local_time = QTime::currentTime();
    //显示的内容
    ui->lcdNumber->display(local_time.toString("hh:mm:ss"));
}
